GO
1. SELinux介绍
SELinux是RedHat和CentOS系统特有的安全机制。如果能够正确使用它,会使网站非常健壮。不过因为这个东西限制太多,配置也特别繁琐,所以几乎没有人真正应用它(包括腾讯公司也不用)。所以装完系统后,我们一般都要把SELinux关闭,以免引起不必要的麻烦。
关闭SELinux的方法如下:
- 临时关闭:
setenforce 0
- 永久关闭:编辑配置文件/etc/selinux/config,使”SELinux=disabled”(默认为enforcing)。保存该配置文件后,需要重启LInux系统才能生效。
获取当前SELinux的状态的方法如下:
getenforce
- 如果没有这个命令,需要安装这个包:libselinux-utils。
- 该命令默认会输出”enforcing”。若是已经永久关闭SELinux了,则会显示”Disabled”。
- 当使用
setenforce 0
临时关闭SELinux之后,再使用getendorce
会输出”permissive”。
2. 防火墙详解
在之前的CentOS版本(比如5或6)的防火墙为netfilter,CentOS7的防火墙为firewalld。而ipdables(netfilter相对应的)只是它的一个实现工具。它的功能非常丰富,但是在日常的管理工作中仅仅会用到一两个应用,这并不代表它不重要。作为一个网络管理员,iptables的各种应用规则是必须要熟练掌握的。但是作为系统管理员,我们也应该会最基本的操作,认识iptables的基本规则。对于CentOS7上的为firewalld,同样也支持之前版本的命令用法。所以下面分别介绍一下这两种的实现工具是如何使用的。
2.1. CentOS6的iptables
如果你现在所用的系统是CentOS6或以前的版本,那么系统默认使用的就是iptables这个工具来管理防火墙的。如果你所使用的是CentOS7版本的系统,那么默认使用的是firewalld来管理防火墙。这时,可以将firewalld关闭,然后开启之前版本的iptables,那么就可以在CentOS7上面使用iptables了。操作如下:
|
|
2.1.1. 查看、清除和保存规则
CentOS上默认是设有iptables规则的,这个规则虽然很安全,但是对于我们来说没有用,反而会造成某些影响,所以建议你先清除规则,然后把清除后的规则保存一下:
iptables -nvL
查看规则iptables -F ; /etc/init.d/iptables save
防火墙规则保存在了/etc/sysconfig/iptables中。- 关于上面两条命令的说明:
-nvL
选项是查看规则,-F
是把当前规则清除,但这个只是临时的,重启系统或者重启iptables服务后还会夹在已经保存的规则,所以需要使用/etc/init.d/iptables save
保存一下规则。当然,service iptables save
的效果是一样的,也是保存防火墙的规则。 iptables -Z
将防火墙中的计数清零
2.1.2. iptables的5个表和5个链
五个表如下:
- filter表
- 这个表主要用于过滤包的,是系统预设的表,这个表也是工作中用的最多的。
- 内建三个链:INPUT、OUTPUT、FORWARD。
- INPUT作用于进入本机的包,OUTPUT作用于本机送出的包,FORWARD作用于那些跟本机无关的包。
- nat表
- 主要用处是网络地址转换,比如公网IP和内网IP之间的转换。也有三个链。
- PREROUTING链的作用是在包刚刚到达防火墙时改变它的目的地址(如果需要的话)。
- OUTPUT链的作用是改变本地产生的包的目的地址。
- POSTROUTING链的作用是在包就要离开防火墙之前改变其源地址。
- 这个表在工作中用的不多,但偶尔会用到。
- mangle表
- 这个表主要用于给数据包作标记,然后根据标记去操作哪些包。
- 这个表几乎不怎么用。除非你想成为高级网络工程师,否则就不需要关注。
- raw表
- 这个表可以实现不追踪某些数据包,默认系统的数据包都会被追踪,但追踪势必消耗一定的资源,所以可以用raw表来指定某些端口的包不被追踪。
- 只有两个链:OUTPUT、PREROUTING。
- 这个表从来不用。
- security表
- 这个表在CentOS6中是没有的,它用于强制访问控制(MAC)的网络规则。
- 这个表也不会被用到,所以不需要关注。
五个链如下:
- PREROUTING链:数据包进入路由表之前
- INPUT链:通过路由表后目的地为本机
- FORWARDING链:通过路由表后,目的地不为本机
- OUTPUT链:由本机产生,向外转发
- POSTROUTING链:发送到网卡接口之前
说明:
- INPUT 进来的-d:local本地(目标)
- OUTPUT 出去的-s:local本地(源)
2.1.3. iptables的基本语法
查看规则以及清除规则
iptables -t nat -nvL
- -t后面跟表名,-nvL即查看该表的规则,其中-n表示不针对IP反解析主机名,-L表示列出的意思,而-v表示列出的信息更加详细。
- 如果不加-t,则打印filter表的相关信息:
iptables -nvL
(这和加上-t filter选项后打印的信息是一样的)
- 关于清除规则的命令中,用的最多的就是:
iptables -F
-F表示把所有规则全部删除iptables -Z
-Z表示把包以及流量计数器置零(这个功能很有用)
增加或删除一条规则
iptables -A INPUT -s 10.72.11.12 -p tcp --sport 1234 -d 10.72.137.159 --dport 80 -j DROP
- 这就是增加了一条规则,省略-t所以针对的是filter表。
- -A表示增加一条规则(放到最后),另外还有-I(大写i)表示插入一条规则(放到嘴前),-D表示删除一条规则。
- 后面的INPUT即链名称,还可以是OUTPUT或者FORWARD。
- -s后面跟源地址。(来处)
- -p 协议(tcp、udp、icmp)
- –sport/–dport 后跟源端口/目标端口。(–dport/–sport必须要和-p选项一起使用,否则会出错)。
- -d 后面跟目的IP(主要针对内网或者外网)。
- -j 后跟动作(DROP即把包丢掉,ERJECT即包拒绝,ACCEPT即允许包)。
- 几个例子:
iptables -I INPUT -s 1.1.1.1 -j DROP
表示:插入一条规则,把来自1.1.1.1的所有数据包丢掉。iptables -D INPUT -s 1.1.1.1 -j DROP
表示:删除刚刚插入的规则。注意,要删除一条规则时,必须和插入的规则一直,也就是说,两条iptables命令,除了-I和-D选项不一样之外,其他地方都一样。iptables -I INPUT -s 2.2.2.2 -p tcp --dport 80 -j DROP
表示:把来自2.2.2.2并且是TCP协议到本机的80端口的数据包丢掉。iptables -I OUTPUT -p tcp --dport 22 -d 10.0.1.14 -j DROP
表示:把发送到10.0.1.14的22端口的数据包丢掉。iptables -A INPUT -s 192.168.1.0/24 -i eth0 -j ACCEPT
表示:把来自192.168.1.0/24这个网段的并且作用在eth0网卡上的包放行。
规则总结:
- -A/-D :增加或删除一条规则
- -I :插入一条规则,其实跟-A的效果差不多(如果想让一条规则最优先生效,那么就用-I插入一条规则)
- -p :指定协议,可以是tcp、udp、icmp
- –dport :跟-p一起使用,指定目标端口
- –sport :跟-p一起使用,指定源端口
- -s :指定源IP(可以是一个IP段)
- -d :指定目的IP(可以是一个IP段)
- -j :后跟动作,其中ACCEPT表示允许包,DROP表示丢掉包,REJECT表示拒绝包
- -i :指定网卡(不常用,但有时候能够用到)
2.1.4. 删除一条规则的简便方法
当iptables的规则过多时,想删除某一条规则时,又不容易掌握当时创建时的规则。其实有一种比较简单的方法,如下所示:
iptables -nvL --line-numbers
查看规则的内容和编号iptables -D INPUT 1
删除编号为1的规则- -D后面跟链名,然后是规则编号n,这个n就是查看iptables规则时第一列的值。
2.1.5. iptables的-P(大写)选项
iptables还有一个选项经常用到,就是-P(大写),表示预设策略。用法如下:
iptables -P INPUT DROP
- 说明:-P后面跟链名,策略内容或者为DROP或者为ACCEPT,默认是ACCEPT。
- 注意:如果你在远程链接服务器,千万不要随便敲这个命令,因为一旦敲完回车后你就会断掉。
- 这个策略一旦设定后,只能使用
iptables -P INPUT ACCEPT
才能回复成原始状态,而不能使用-F参数。
下面针对一个小需求讲解一下这个iptables规则如何设定:、
- 需求:之针对filter表,预设策略INPUT链DROP,其他两个ACCEPT,然后针对192.168.137.0/24开通22端口,对所有网段开放80端口,对所有网段开放21端口。
解决方法:这个需求不算复杂,但是因为有很多条规则,所以最好写成脚本的形式。脚本内容如下:
123456789# cat /usr/local/sbin/iptables.shipt="/sbin/iptables"$ipt -P INPUT DROP$ipt -P OUTPUT ACCEPT$ipt -P FORWARD ACCEPT$ipt -A INPUT -s 192.168.137.0/24 -p tcp --dport 22 -j ACCEPT$ipt -A INPUT -p tcp --dport 80 -j ACCEPT$ipt -A INPUT -p tcp --dport 21 -j ACCEPT完成脚本的编写后,直接运行
/bin/sh /usr/local/sbin/iptables.sh
即可。- 如果想开机启动时初始化防火墙规则,则需要在/etc/rc/d/rc.local中添加一行
/bin/sh /usr/local/sbin/iptables.sh
2.1.6. 关于icmp的包的一个常见应用
iptables -I INPUT -p icmp --icmp-type 8 -j DROP
说明:--icmp-type
这个选项要跟-p icmp
一起使用的,后面指定类型编号。这个8指的是能在本机ping通其他机器,而其他机器不能ping通本机。这个有必要记一下。
2.1.7. nat表的应用
引言:在日常生活中相信你接触过路由器吧,它的功能就是分享上网。本来一根网线过来(其实只有一个公网IP),通过路由器后,路由器分配了一个网段(私网IP),这样连接路由器的多台设备就都能够连接网络了。而远端的设备认为你的IP就是那个连接路由器的公网IP。这个luyouqi的功能其实就是由Linux的netfilter的nat表实现的。
需求:假设你的机器上有两块网卡eth0和eth1,其中eth0的IP为10.0.2.68,eth1的IP为192.168.1.1。eth0连接了网络,但eth1没有连接,现在有另一台机器(192.168.1.2)和eth1是互通的,那么如何设置也能够让连接eth1的这台机器能够连上网络呢(即能和10.0.2.68互通)?
解决方法如下:
echo "1" > /proc/sys/net/ipv4/ip forward
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
- 说明:
- 就是这样简单的两条命令就能实现上面的需求。第一个命令涉及到了内核参数相关的配置文件,它的目的是为了打开路由转发的功能,否则无法实现我们的应用。
- 第二个命令则是对nat表做了一个IP转发的操作,-o选项后面跟设备名,表示出口的网卡,MASQUERADE表示伪装的意思。
- 关于nat表,暂时先不讲太多内容,只需要学会这个路由转发即可。
2.1.8. 保存以及备份iptables规则
- 保存:
- 设定的防火墙规则只是保存在内存中,并没有保存到某一个文件中,也就是说当系统重启后以前设定的规则就没有了,所以设定规则后要先保存一下。、
service iptables save
- 它会提示防火墙规则保存在了/etc/sysconfig/iptables文件内,这个文件就是iptables的配置文件了。
- 备份:
- 所谓防火墙的备份就是把防火墙的配置文件/etc/sysconfig/iptables备份一下
- 有时候我们会需要把防火墙的所有规则都清除,使用
iptables -F
命令虽然可以,但是最好的办法是把防火墙服务停止:service iptables stop
- 说明:这样防火墙就失效了,但是一旦重新设定规则后(哪怕只有一条),防火墙服务就会自动开启。
- 一个用来备份和还原防火墙规则的命令:
- 备份:
iptables-save > myipt.rule
- 还原:
iptables-restore < myipt.rule
- 备份:
2.1.9. iptables的扩展内容
- iptables应用在一个网段:
一个例子:iptables -I INPUT -m iprange --src-range 61.4.176.0-61.4.191.255 -j DROP
2.2. CentOS7的firewalld
CentOS7版本中集成了多款防火墙管理工具,其中firewalld(Dynamic Firewall Manager of Linux system,Linux系统的动态防火墙管理器)服务是默认的防火墙配置管理工具,它拥有基于CLI(命令行界面)和基于GUI(图形用户界面,工具是firewall=config)的两种管理方式。
相较于传统的防火墙管理配置工具,firewalld支持动态更新技术并加入了区域(zone)的概念,还有一个service的概念。简单来说,区域就是firewalld预先准备了几套防火墙策略集合(策略模板),用户可以根据生产场景的不同而选择合适的策略集合,从而实现防火墙策略之间的快速切换。
2.2.1. 9个zone介绍
firewalld中常见的区域名称(默认为public)以及相应的策略规则如下表所示:
区域 | 默认策略规则 |
---|---|
trusted(信任) | 允许所有的数据包 |
home(家庭) | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、mdns、ipp-client、amba-client与dhcpv6-client服务相关,则允许流量 |
internal(内部) | 等同于home |
work(工作) | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、ipp-client与dhcpv6-client服务相关,则允许流量 |
public(公共) | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、dhcpv6-client服务相关,则允许流量 |
external(外部) | 特别是为路由器启用了伪装功能的外部网。你不能信任来自网络的其它计算,不能相信它们不会对你的计算机造成危害,只能接受经过选择的连接 |
dmz(非军事区) | 用于你的非军事区内的计算机,此区域内可公开访问,可以有限地进入你的内部网络,仅仅接收经过选择的连接 |
block(限制) | 任何接收的网络连接都被IPv4的icmp-host-prohibited信息和IPv6的icmp6-adm-prohibited信息所拒绝 |
drop(丢弃) | 任何接收的网络数据包都被丢弃,没有任何回复。仅能有发送出去的网络连接 |
对于以上9个zone简单了解即可,因为这些在日常工作中使用它们的机会不会太多。下面是一些关于zone的命令:
firewall-cmd --set-default-zone=work
设定默认的zone为workfirewall-cmd --get-zone-of-interface=ens33
查看指定网卡所在的zonefirewall-cmd --zone=public --add-interface=lo
给指定网卡设置zonefirewall-cmd --zone=dmz --change-interface=lo
针对网卡更改zonefirewall-cmd --zone=dmz --remove-interface=lo
针对网卡删除zonefirewall-cmd --get-active-zones
查看系统所有网卡所在的zonefirewall-cmd --get-zones
查看系统所有的zonefirewall-cmd --get-default-zone
查看系统默认的zone
2.2.2. service介绍
其实,之所以有9种zone,是因为每一个zone里面都使用了不同的service,而service就是针对一个服务(端口)做的iptables规则。
这个命令可以列出系统所有的service:firewall-cmd --get-service
这些service都是由一个个配置文件定义的,配置文件的模板在/usr/lib/firewalld/services/目录下,真正生效的配置是在/etc/firewalld/service/目录下面(默认为空)
因为每个zone里面都有不同的service,可以用如下命令来查看一个zone下面有哪些service:
firewall-cmd --list-services
查看当前zone下有哪些servicefirewall-cmd --zone=public --list-services
查看指定zone下有哪些service
|
|
一个zone下面有某个service,意味着这个service是被信任的。比如,当前zone下面有ssh,那么ssh服务(也就是22)端口是方形的。我们可以给一个zone添加一个service,命令如下:
firewall-cmd --zone=public --add-service=http
把http添加到public zone下面1234[root@theshu ~]# firewall-cmd --zone=public --add-service=httpsuccess[root@theshu ~]# firewall-cmd --list-servicesssh dhcpv6-client http
对于每个zone来说,都有自己的配置文件,你可以查看目录/usr/lib/firewalld/zones/下面对应的文件,这些就是zone的配置文件:
上面所说的可以在一个zone里面添加一个service的方法,仅仅是在内存中生效,并没有修改配置文件,如果想修改配置文件,需要加一个选项--permanent
,如下:
一旦更改了某个zone的配置文件,则会在/etc/firewalld/zones/目录下面生成对应zone的配置文件(.xml后缀的文件),其实这个目录下面的配置文件才是真正的配置文件。而上面所介绍的目录,可以说是所有zone的模板配置文件。
2.2.3. firewalld的一个示例
通过这个示例可以更方便的理解zone和service这两个概念。
需求:假如服务器上配置了一个FTP服务,但端口并非默认的21,而是1121,并且需要在woek zone下面放行FTP。
具体做法如下:
再来验证一下work zone里面的service是否有FTP:
2.2.4. firewall-cmd命令及其常用参数总结
参数 | 作用 |
---|---|
–get-zones | 查看系统所有可用的zone |
–get-default-zone | 查看系统默认的zone |
–set-default-zone=work | 设定默认的zone为work |
–get-services | 显示预先定义的服务 |
–get-active-zones | 查看系统所有网卡所在的zone |
–add-source= | 将源自此IP或子网的流量导向某个指定区域 |
–remove-source= | 不再将源自此IP或子网的流量导向某个指定区域 |
–add-interface=网卡名称 | 将源自该网卡的所有流量都导向某个指定区域 |
–change-interface=网卡名称 | 将某个网卡与区域进行关联 |
–remove-interface=网卡名称 | 将某个网卡与区域取消关联 |
–get-zone-of-interface=ens33 | 查看指定网卡所在的zone |
–zone=public –add-interface=lo | 给指定网卡设置zone |
–zone=dmz –change-interface=lo | 针对网卡更改zone |
–zone=dmz –remove-interface=lo | 针对网卡删除zone |
–list-all | 显示当前区域的网卡配置参数、资源、端口以及服务等信息 |
–list-all-zones | 显示所有区域的网卡配置参数、资源、端口以及服务等信息 |
–add-service=服务名 | 设置默认区域允许该服务的流量 |
–add-port=端口号/协议 | 设置默认区域允许该端口的流量 |
–remove-service=服务名 | 设置默认区域不再允许该服务的流量 |
–remove-port=端口好/协议 | 设置默认区域不再允许该端口的流量 |
–permanent | 让配置的防火墙策略永久生效 |
–reload | 让“永久生效”的配置规则立即生效,并覆盖当前的配置规则 |
–panic-on | 开启应急状态模式 |
–panic-off | 关闭应急状态模式 |
2.2.5. firewalld的一些实验
- 查看firewalld服务当前所使用的区域:
firewall-cmd get-default-zone
显示public
- 查询eno16777728网卡在firewalld服务中的区域:
firewall-cmd --get-zone-of-interface=eno16777728
显示public
- 把firewalld服务中eno16777728网卡的默认区域修改为external,并在系统重启后生效。分别查看当前与永久模式下的区域名称:
firewall-cmd --permanent --zone=external --change-interface=eno16777728
显示success
firewall-cmd --get-zone-of-interface=eno16777728
显示public
firewall-cmd --permanent --get-zone-of-interface=eno16777728
显示external
- 把firewalld服务的当前默认区域设置为public:
firewall-cmd --set-default-zone=public
显示success
firewamm-cmd --get-default-zone
显示public
- 启动/关闭firewalld防火墙服务的应急状况模式,阻断一切网络连接(当远程控制服务器时请慎用):
firewall-cmd --panic-on
显示success
firewall-cmd --panic-off
显示success
- 查询public区域是否允许请求SSH和HTTPS协议的流量:
firewall-cmd --zone=public --query-service=ssh
显示yes
firewall-cmd --zone=public --query-service=https
显示no
- 把firewalld服务中请求HTTPS协议的流量设置为永久允许,并立即生效:
firewall-cmd --zone=public --add-service=https
显示success
firewall-cmd --permanent --zone=public --add-service=https
显示success
firewall-cmd --reload
显示success
- 把firewalld服务中请求HTTP协议的流量设置为永久拒绝,并立即生效:
firewall-cmd --permanent --zone=public --remove-service=http
显示success
firewall-cmd --reload
显示success
- 把在firewalld服务中访问8080和8081端口的流量策略设置为允许,但仅限当前生效:
firewall-cmd --zone=public --add-port=8080-8081/tcp
显示success
firewall-cmd --zone=public --list-ports
显示8080-8081/tcp
- 把原本访问本机888端口的流量转发到22端口,且要求当前和长期均有效:
- 注意:流量转发的命令格式为
firewall-cmd --permanent --zone=区域 --add-forward-port=port=源端口号:proto=协议:toport=目标端口号:toaddr=目标IP地址
firewall-cmd --permanent --zone=public --add-forward-port=port=888:proto=tcp:toport=22:toaddr=192.168.10.10
显示success
firewall-cmd --reload
显示success
- 注意:流量转发的命令格式为
firewalld中锋富规则表示更细致、更详细的防火墙策略配置,它可以针对系统服务、端口号、源地址和目标地址等诸多信息进行更有针对性的策略配置。它的优先级在所有的防火墙策咯中也是最高的。比如,我们可以在firewalld服务中配置一条富规则,使其拒绝192.168.10.0/24网段的所有用户访问本机的ssh服务(22端口),如下所示:
在客户端使用ssh命令尝试访问192.168.10.10主机的ssh服务(22端口):
3. 服务的访问控制列表
服务的访问控制列表指的是这两个文件:
- /etc/hosts.allow:允许控制列表文件
- /etc/hosts.deny:拒绝控制列表文件
TCP Wrappers 是 CentOS7系统中默认启用的一款流量监控程序,它能够根据来访主机的地址与本机的目标服务程序做出允许或拒绝的操作。换句话说,Linux系统中其实有两个层面的防火墙,第一种是前面讲到的基于TCP/IP协议的流量过滤工具,而TCP Wrappers服务则是能允许或禁止Linux系统提供服务的防火墙,从而在更高层面保护了Linux系统的安全运行。
TCP Wrappers服务的防火墙策略由两个控制列表文件所控制,用户可以编辑允许控制列表文件来放行对服务的请求流量,也可以编辑拒绝控制列表文件来阻止对服务的请求流量。控制列表文件修改后会立即生效,系统将会先检查允许控制列表文件(/etc/hosts.allow),如果匹配到相应的允许策略则放行流量;如果没有匹配,则会进一步匹配拒绝控制列表文件(/etc/hosts.deny),若找到匹配项则拒绝该流量。如果这两个文件都没有匹配到,则默认放行流量。
3.1. 常用参数和原则
TCP Wrappers服务的控制列表文件配置起来并不复杂,常用参数如下表所示:
客户端类型 | 示例 | 满足示例的客户端列表 |
---|---|---|
单一主机 | 192.168.10.10 | IP地址为192.168.10.10的主机 |
指定网段 | 192.168.10. | IP段为192.168.10.0/24的主机 |
指定网段 | 192.168.10.0/255.255.255.0 | IP段为192.168.10.0/24的主机 |
指定DNS后缀 | .theshu.top | 所有DNS后缀为.theshu.top的主机 |
指定主机名称 | www.theshu.top | 主机名称为www.theshu.top的主机 |
指定所有客户端 | ALL | 所有主机全部包括在内 |
在配置TCP Wrappers服务时需要遵循两个原则:
- 编写拒绝策略规则时,填写的是服务名称,而非协议名称
- 建议先编写拒绝策略规则,再编写允许策略规则,以便直观地看到相应的效果
3.2. 示例
下面编写拒绝策略规则文件,禁止访问本机sshd服务的所有流量(无需/etc/hosts/deny文件中修改原有的注释信息):
接下来,在允许策咯规则文件中添加一条规则,使其放行源自192.168.10.0/24网段,访问本机sshd服务的所有流量。可以看到,服务器立刻就放行了访问sshd服务的流量。,效果非常直观:
OK